<?php

namespace App\Service\UserService;

use App\Model\CommodityModel\SupplierCompany;
use App\Model\CommodityModel\WarehouseInfo;
use App\Model\PssModel\Business;
use App\Model\PssModel\PddToken;
use App\Service\AppService\SystemCacheConfigService;
use App\Service\BaseService;
use App\Service\Code\Normal;
use App\Service\VendorClient\CommonDataService\CommonDataApiClient;
use Service\AppService\IdService;

/**
 * 关务渠道和云仓供应商及渠道打通服务
 * @author chenshubo
 */
class CustomToYunCangUserService extends BaseService
{
    const THIRD_PARTY_PLAT_FORM_CODE = 'shopcustom';
    const TAG = 'mb';

    /**
     * 新增数据接口
     * @param array $param
     */
    public function addUser(array $param = [])
    {
        if (!isset($param['isNeedCreateChannel'])) {
            return Normal::returnCode(Normal::FAIL, "isNeedCreateChannel参数缺失!");
        }

        if (empty($param['customGateWayURL'])) {
            return Normal::returnCode(Normal::FAIL, "customGateWayURL不能为空!");
        }

        if (empty($param['customerCode'])) {
            return Normal::returnCode(Normal::FAIL, "customerCode不能为空!");
        }

        if (empty($param['userMode'])) {
            return Normal::returnCode(Normal::FAIL, "userMode不能为空!");
        }

        $userMode = ucfirst(strtolower($param['userMode']));
        $class_name = "App\\Service\\UserService\\SubUserRouterService\\{$userMode}";
        if (!class_exists($class_name)) {
            return Normal::returnCode(Normal::FAIL, "userMode: {$userMode} 业务不存在，请联系管理员仔细核对!");
        }

        $method = 'getAddUserData';
        if (!method_exists($class_name, $method)) {
            return Normal::returnCode(Normal::FAIL, "业务类 {$class_name} 不存在方法{$method},请联系管理员仔细核对!");
        }

        $_result_check = $class_name::instance()->{$method}($param);
        if ($_result_check['code'] != Normal::SUC) {
            return Normal::returnCode(Normal::FAIL, "userMode: {$userMode} 业务下：{$_result_check['msg']}");
        }

        $extends = $_result_check['data'];
        
        //判断货主编码信息是否已存在
        $supplierCodeInfo = SupplierCompany::instance()->where(['SupplierCode' => $param['customerCode']])->first();
        if( !empty($supplierCodeInfo) ) 
        {
            if( $supplierCodeInfo->SupplierName != $param['channelName'] ) 
            {
                return Normal::returnCode(Normal::FAIL, "当前渠道商货主编码【{$param['customerCode']}】对应供应商名称【{$supplierCodeInfo->SupplierName}】在中台已存在，且和您需要添加的货主名称【{$param['channelName']}】不一致，请更换!");
            }
        }
        
        //判断货主名称信息是否已存在
        $supplierNameInfo = SupplierCompany::instance()->where(['SupplierName' => $param['channelName']])->first();
        if( !empty($supplierNameInfo) )
        {
            if( $supplierNameInfo->SupplierCode != $param['customerCode'] )
            {
                return Normal::returnCode(Normal::FAIL, "当前渠道商货主名称【{$param['channelName']}】对应供应商编码【{$supplierNameInfo->SupplierCode}】在中台已存在，且和您需要添加的货主编码【{$param['customerCode']}】不一致，请更换!");
            }
        }
        
        //先判断是否供应商是否为存在情况
        $supplier = SupplierCompany::instance()->where([
            'SupplierName' => $param['channelName'],
            'SupplierCode' => $param['customerCode']
        ])->first();
        
        //是否需要创建渠道商
        $isNeedCreateChannel  = $param['isNeedCreateChannel'];

        //已经创建过供应商数据
        if (!empty($supplier)) 
        {
            $supplier = $supplier->toArray();
            if ($isNeedCreateChannel) {
                if( $param['userMode'] == 'pdd' ) {
                    //修改PddToken表
                    PddToken::instance()->where('mall_id',$param['extends']['shopID'])->update([
                        'extends' => json_encode($extends,JSON_UNESCAPED_UNICODE)
                    ]);
                }
            }
        }
        else
        {
            try {
                
                Business::instance()->startTrans();
                SupplierCompany::instance()->startTrans();
                
                //这里先创建供应商和仓库
                $data = $this->addYuncangSupplierAndWarehouse($param);
                $supplier = $data['supplier'];
                
                //创建渠道
                if ( $isNeedCreateChannel )
                {
                    $res = $this->insertChannel($extends,$param);
                    if ($res['code'] != Normal::SUC)  {
                        Business::instance()->rollback();
                        SupplierCompany::instance()->rollback();
                        return $res;
                    }
                }
                
                $res = $this->insertSupplierData($data);
                if ($res['code'] != Normal::SUC) {
                    Business::instance()->rollback();
                    SupplierCompany::instance()->rollback();
                    return Normal::returnCode(Normal::FAIL,"创建供应商失败,请联系管理员处理");
                }
                
                //两个数据库统一提交事务
                Business::instance()->commit();
                SupplierCompany::instance()->commit();
            }
            catch (\Exception $e)
            {
                Business::instance()->rollback();
                SupplierCompany::instance()->rollback();
                return Normal::returnCode(Normal::FAIL, $e->getMessage());
            }
        }
        
        $url = '';
        $config=SystemCacheConfigService::instance()->getCacheInfoBySystemCode('sysconfig');
        if (!empty($config['NotifyUrl'])){
            $url = $config['NotifyUrl'].'/Notify/index/userType/shopgw/messageType/MessageRev/supplierID/'. $supplier['ID'];
        }

        return Normal::returnCode(Normal::SUC, "处理成功", [
            'url' => $url
        ]);
    }

    /**
     * 创建供应商和仓库信息
     * @return
     */
    private function addYuncangSupplierAndWarehouse($params)
    {
        //查询配置
        $supplierID = IdService::instance()->getOtherID();
        $supplier = [
            'ID'                        => $supplierID,
            'SupplierName'              => $params['channelName'],
            'SupplierCode'              => $params['customerCode'],
            'CompanyStatus'             => 1,
            'SettlementMethod'          => 0,
            'OrderDeclare'              => 0,
            'PayDeclare'                => 1,
            'OrderDockMode'             => 0,
            'IsOpenSupplierSettleIn'    => 0,
            'SupplierAlias'             => '',
            'EnterpriseName'            => '',
            'EnterpriseCode'            => '',
            'ShowInPreferred'           =>  1,
            'IsTryUpdateCommodityArchives' => 1,
            'IsBbcCommodity'            => 0,
            'CreateTime'                => date('Y-m-d H:i:s'),
            'IsDeleted'                 => 0,
            'File'                      => json_encode([], JSON_UNESCAPED_UNICODE),
            'ThirdPartyPlatformCode'    => self::THIRD_PARTY_PLAT_FORM_CODE,
            'AdminAccount'              => '',
            'BusinessLicenseNo'         => '',
            'IsLockStock'               => 0,
            'FastDeliveryType'          => 0
        ];
        
        $configs = CommonDataApiClient::instance()->queryThirdPartyPlatform([
            'ThirdPartyPlatformCode' => self::THIRD_PARTY_PLAT_FORM_CODE
        ]);

        $configMap = array_column($configs['data'], null, 'Code');
        $jsonBody = $configMap[self::THIRD_PARTY_PLAT_FORM_CODE]['DefaultJsonBody'] ?? [];
        $jsonBody['baseurl'] = $params['customGateWayURL'];
        $jsonBody['customercode'] = $params['customerCode'];

        $warehouse = [
            'ID'                => IdService::instance()->getOtherID(),
            'SupplierID'        => $supplierID,
            'WarehouseCode'     => $params['customerCode'],
            'WarehouseName'     => $params['channelName'],
            'WarehouseType'     => 1,
            'IsCombineOrders'   => 1,
            'ExamineState'      => 1,
            'WarehouseAccount'  => $params['customerCode'],
            'CanModifyStock'    => 0 ,
            'CanModifyPrice'    => 0 ,
            'CreateTime'        => date('Y-m-d H:i:s'),
            'IsDeleted'         => 0,
            'JsonBody'          => json_encode($jsonBody, JSON_UNESCAPED_UNICODE),
        ];

        return ['supplier' => $supplier, 'warehouse' => $warehouse];

    }

    /**
     * 写入供应商
     * @param array $data
     * @return unknown[]|string[]|array[]
     */
    public function insertSupplierData(array $data)
    {
        try {
            SupplierCompany::instance()->insert($data['supplier']);
            WarehouseInfo::instance()->insert($data['warehouse']);
            return Normal::returnCode(Normal::SUC, '创建成功');
        }catch (\Exception $e){
            return Normal::returnCode(Normal::FAIL, $e->getMessage());
        }
    }

    /**
     * 写入渠道商和多多表
     * @param array $extends
     * @param string $shopID
     * @throws \Exception
     * @return unknown[]|string[]|array[]
     */
    public function insertChannel(array $extends,array $param)
    {
        
        $shopID     = $param['extends']['shopID'];
        $userMode   = $param['userMode'];
        
        //先查询是否有授权数据
        $pddInfoObj = PddToken::instance()->where('mall_id',$shopID)->first();

        if (empty($pddInfoObj)){
            return Normal::returnCode(Normal::FAIL,'没有找到拼多多授权数据');
        }
        
        $pddInfo = $pddInfoObj->toArray();
        if( !empty($pddInfo['bid']) ) {
            return Normal::returnCode(Normal::FAIL,'当前店铺渠道数据已绑定，无须重复绑定!');
        }
        
        $sender = $extends['senderUserInfo'];
        $has = Business::instance()->where('account',$sender['mobile'])->first();
        if( !empty($has) ) {
            return Normal::returnCode(Normal::FAIL,'当前渠道联系人手机号码账号已经存在，请更换!');
        }
        
        try {
            $addBusArr = [
                'name'                  => $pddInfo['mall_name'],
                'linkphone'             => $sender['mobile'],
                'address'               => $sender['address']['district'],
                'account'               => $sender['mobile'],
                'linkname'              => $sender['name'],
                'settlement'            => 1,
                'settlement_warn_money' => 0.00,
                'is_market_price_send'  => 0,
                'is_channel'         	=> 2,
                'order_declare'      	=> 0,
                'pay_declare'        	=> 1,
                'password'           	=> md5($sender['mobile']),
                'cd'                 	=> time(),
                'verify_status'      	=> 1,
                'user_source'        	=> 2,
                'user_type'          	=> 2,
                'is_router_user'     	=> 1,
                'user_tax_mode'      	=> 0,
                'is_mult_shop'       	=> 1,
                'is_skip_declare'    	=> 0,
                'is_push_goods'      	=> 1,
                'user_tag'           	=> $userMode,
                'order_get_tag'         => 'customjx',
                'is_support_aftersale_verify' => 0
            ];
            
            $bid = Business::instance()->insertGetId($addBusArr);

            $appId  = $this->createAppId($bid);
            $secret = $this->createSecret($bid,$appId);
            $res = Business::instance()->where('id',$bid)->update(['appid'=>$appId,'secret'=>$secret]);

            if( !$res ) {
                throw new \Exception('创建渠道失败,请联系管理员处理');
            }

            PddToken::instance()->where('mall_id',$shopID)->update([
                'extends'   => json_encode($extends,JSON_UNESCAPED_UNICODE),
                'bid'       => $bid,
                'md'        => time(),
                'status'    => 1
            ]);
            
            return Normal::returnCode(Normal::SUC, '创建成功');

        }catch (\Exception $e){
            return Normal::returnCode(Normal::FAIL, $e->getMessage());
        }

    }

    /**
     * 创建appid
     * @param $bid
     * @return string
     */
    private function createAppId($bid = 0)
    {
        return self::TAG.sha1($bid.$this->createNoticeStr());
    }

    private function createSecret($bid = 0,$appId = '')
    {
        $string = $bid .$appId .time();
        return sha1(md5($string));
    }

    private function createNoticeStr() {
        $time = substr(date("YmdHis", time()), 3);
        $randNum =$this->randString();
        if (is_numeric($randNum)) {
            //纯数字检测，如果是纯数字，重新调用该方法
            $b = $this->createNoticeStr();
            $uuid = $time . $b;
        } else {
            $uuid = $time . $randNum;
        }
        //因为生成的Id是15位的，所以取最后的15位
        return substr($uuid, -15);
    }

    private function randString() {
        $characters = '0123456789abcdefghijklmnopqrstuvwxyz';
        $randomString = '';
        for ($i = 0; $i < 4; $i++) {
            $randomString .= $characters[rand(0, strlen($characters) - 1)];
        }
        return $randomString;
    }
}